package org.libarae.communication.response;

import java.io.ByteArrayOutputStream;
import java.util.Vector;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.libarae.communication.XmlParseException;
import org.libarae.communication.common.Book;
import org.libarae.communication.common.Type;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;


public class ProfileTabResponse extends Response{
	private Vector<Book> mUserBookList = new Vector<Book>();
	private Vector<Book> mCheckedOutBookList = new Vector<Book>();
	private int mUnreadMessagesCount, mStatUserStat; //TODO discuss and fill out
	
	public ProfileTabResponse(int status){
		super(Type.PROFILE_TAB, status);		
	}
	
	public ProfileTabResponse(int status, Vector<Book> userBooks, Vector<Book> checkedOut, int unreadMessages){
		super(Type.PROFILE_TAB, status);
		setUnreadMessagesCount(unreadMessages);
		setUserBookList(userBooks);
		setCheckedOutBookList(checkedOut);
	}	
	
	public ProfileTabResponse(int status, Vector<Book> userBooks, Vector<Book> checkedOut, int unreadMessages, int statUserStat){
		super(Type.PROFILE_TAB, status);
		setUnreadMessagesCount(unreadMessages);
		setCheckedOutBookList(checkedOut);
		setUserBookList(userBooks);
	}	
	
	@Override
	public String createXML() throws XmlParseException {
		Document doc;
		try{
			//setup the factory to build the xml
			DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
			doc = documentBuilder.newDocument();
		}
		catch (Exception e) {
			throw new XmlParseException("Error creating XML Builder",e);
		}
		
		//create the xml
		Element rootElement = doc.createElement("type");
		rootElement.setAttribute("typeID", super.getType()+"");
		doc.appendChild(rootElement);
		//user name
		Element node = doc.createElement("mStatus");
		node.setTextContent(getStatus()+"");
		rootElement.appendChild(node);
		
		node = doc.createElement("mUserBookList");
		for(Book b : mUserBookList){
			Element subNode =  doc.createElement("Book");
			b.setPicture(null);
			b.createXml(doc, subNode);
			node.appendChild(subNode);
		}	
		rootElement.appendChild(node);
		
		node = doc.createElement("mCheckedOutBookList");
		for(Book b : mCheckedOutBookList){
			Element subNode =  doc.createElement("Book");
			b.setPicture(null);
			b.createXml(doc, subNode);
			node.appendChild(subNode);
		}	
		rootElement.appendChild(node);

		node = doc.createElement("mUnreadMessagesCount");
		node.setTextContent(mUnreadMessagesCount+"");
		rootElement.appendChild(node);
		
		node = doc.createElement("mStatUserStat");
		node.setTextContent(mStatUserStat+"");
		rootElement.appendChild(node);
		
		//export the xml to a string
		String output = null;
		try {
			ByteArrayOutputStream byteArrayOutput = new ByteArrayOutputStream();
			TransformerFactory transformerFactory = TransformerFactory.newInstance();
			Transformer transformer = transformerFactory.newTransformer();
			DOMSource source = new DOMSource(doc);
			StreamResult result = new StreamResult(byteArrayOutput);
			transformer.transform(source, result);
			output = byteArrayOutput.toString();
		}
		catch (Exception e) {
			throw new XmlParseException("Error outputting XML to string", e);
		}
		
		//return the string
		return output;
	}

	@Override
	public void decodeXML(Document document) {
		// get the document root and node list
		Element root = document.getDocumentElement();
		NodeList nodeList = root.getChildNodes();

		// set all of the nodes in their proper places
		for (int i = 0; i < nodeList.getLength(); i++) {
			// find what node we have
			String nodeName = nodeList.item(i).getNodeName();
			if (nodeName.equals("mStatus")) {
				setStatus(Integer.parseInt(nodeList.item(i).getTextContent()));
			}
			else if (nodeName.equals("mUserBookList")) {
				NodeList nodeVector = nodeList.item(i).getChildNodes();
				mUserBookList = new Vector<Book>();
				for(int p = 0; p < nodeVector.getLength(); p++){
					Book book = new Book();
					book.decodeXML(nodeVector.item(p));					
					mUserBookList.add(book);
				}
			}
			else if (nodeName.equals("mCheckedOutBookList")) {
				NodeList nodeVector = nodeList.item(i).getChildNodes();
				mCheckedOutBookList = new Vector<Book>();
				for(int p = 0; p < nodeVector.getLength(); p++){
					Book book = new Book();
					book.decodeXML(nodeVector.item(p));					
					mCheckedOutBookList.add(book);
				}
			}
			else if (nodeName.equals("mUnreadMessagesCount")) {
				mUnreadMessagesCount = Integer.parseInt(nodeList.item(i).getTextContent());
			}
			else if (nodeName.equals("mStatUserStat")) {
				mStatUserStat = Integer.parseInt(nodeList.item(i).getTextContent());
			}
			else {
				System.err.println("Unknow field in object XML: " + nodeName);
			}
		}	
	}


	/**
	 * @return the mUserBookList
	 */
	public Vector<Book> getUserBookList() {
		return mUserBookList;
	}


	/**
	 * @param mUserBookList the mUserBookList to set
	 */
	public void setUserBookList(Vector<Book> mUserBookList) {
		if(mUserBookList == null)
			this.mUserBookList = new Vector<Book>();
		else
			this.mUserBookList = mUserBookList;
	}


	/**
	 * @return the mCheckedOutBookList
	 */
	public Vector<Book> getCheckedOutBookList() {
		return mCheckedOutBookList;
	}


	/**
	 * @param mCheckedOutBookList the mCheckedOutBookList to set
	 */
	public void setCheckedOutBookList(Vector<Book> mCheckedOutBookList) {
		if(mCheckedOutBookList == null)
			this.mCheckedOutBookList = new Vector<Book>();
		else
			this.mCheckedOutBookList = mCheckedOutBookList;
	}


	/**
	 * @return the mUnreadMessagesCount
	 */
	public int getUnreadMessagesCount() {
		return mUnreadMessagesCount;
	}


	/**
	 * @param mUnreadMessagesCount the mUnreadMessagesCount to set
	 */
	public void setUnreadMessagesCount(int mUnreadMessagesCount) {
		this.mUnreadMessagesCount = mUnreadMessagesCount;
	}


	/**
	 * @return the mStatUserStat
	 */
	public int getStatUserStat() {
		return mStatUserStat;
	}


	/**
	 * @param mStatUserStat the mStatUserStat to set
	 */
	public void setStatUserStat(int mStatUserStat) {
		this.mStatUserStat = mStatUserStat;
	}

	@Override
	public String createHTML() {
		// TODO Auto-generated method stub
		return null;
	}

}
